#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Side-Channel Attack统一管理器
Provide统一的Attack接口And管理功能

Template AttackUseExample:

# BasicUse (自动FromAlgorithm模型Configuration)
manager = SideChannelAttackManager()
manager.load_data("traces.npz", "aes")
result = manager.run_basic_attack("template", target_byte=0)

# Configuration化Template Attack (指定目标操作And泄漏模型)
result = manager.run_basic_attack(
    "template", 
    target_byte=0,
    target_operation="sbox_output",  # Optional: sbox_input, round_key_xor, etc.
    leakage_model="hamming_weight"   # Optional: identity, Or模型Class中定义的其他模型
)

# 获取AlgorithmSupport的Configuration
supported_algos = manager.get_template_attack_supported_algorithms()
aes_info = manager.get_algorithm_template_info("aes")
print(f"AESSupport的操作: {aes_info['target_operations']}")
print(f"AESSupport的泄漏模型: {aes_info['leakage_models']}")

# 自定义AlgorithmSupport (回退方案)
def my_intermediate_func(plaintext, key, hypothesis):
    if key is not None:
        return some_operation(plaintext, key)
    else:
        return some_operation(plaintext, hypothesis)

def my_leakage_func(intermediate_value):
    return bin(intermediate_value).count('1')

manager.set_template_attack_functions("custom_algo", my_intermediate_func, my_leakage_func)
result = manager.run_basic_attack("template", target_byte=0)
"""

import os
import sys
import time
import json
import logging
import numpy as np
from pathlib import Path
from typing import Dict, Any, List, Optional, Union
from dataclasses import dataclass, asdict

# AddCurrentDirectoryToPath
sys.path.insert(0, str(Path(__file__).parent))

# 导入基础AttackModule
from base_side_channel_attack import AttackResult
from cpa_attack import CPAAttack
from dpa_attack import DPAAttack
from spa_attack import SPAAttack
from template_attack import TemplateAttack

# 导入Algorithm特定AttackModule
from algorithm_specific_attacks import (
    ALGORITHM_ATTACKS,
    get_algorithm_attack,
    AlgorithmSpecificResult
)


@dataclass
class AttackConfiguration:
    """AttackConfiguration"""
    algorithm: str = "aes"
    attack_type: str = "cpa"
    target_byte: int = 0
    target_operation: str = "sbox_output"
    threshold: float = 0.1
    verbose: bool = False
    save_results: bool = True
    output_dir: str = "attack_results"


class SideChannelAttackManager:
    """Side-Channel Attack统一管理器"""
    
    def __init__(self, log_level: str = "INFO"):
        """
        InitializeAttack管理器
        
        Args:
            log_level: 日志级别
        """
        self.logger = self._setup_logging(log_level)
        
        # Data存储
        self.traces = None
        self.plaintexts = None
        self.ciphertexts = None
        self.keys = None
        self.algorithm = None
        
        # Attack器实例
        self.basic_attacks = {
            'cpa': CPAAttack(),
            'dpa': DPAAttack(),
            'spa': SPAAttack(),
            'template': None  # Template AttackRequire特殊Initialize
        }
        
        # Template Attack实例缓存
        self.template_attacks = {}
        
        # Algorithm特定Attack器
        self.algorithm_attacks = {}
        
        self.logger.info("Side-Channel Attack管理器InitializeCompleted")
    
    def _setup_logging(self, log_level: str) -> logging.Logger:
        """Settings日志"""
        logger = logging.getLogger("AttackManager")
        logger.setLevel(getattr(logging, log_level.upper()))
        
        if not logger.handlers:
            handler = logging.StreamHandler()
            formatter = logging.Formatter(
                '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
            )
            handler.setFormatter(formatter)
            logger.addHandler(handler)
        
        return logger
    
    def _get_template_attack(self, algorithm: str = None, target_operation: str = "sbox_output", 
                           leakage_model: str = "hamming_weight") -> TemplateAttack:
        """
        获取Algorithm特定的Template Attack实例
        
        Args:
            algorithm: Algorithm名称，DefaultUseCurrentAlgorithm
            target_operation: 目标操作
            leakage_model: 泄漏模型
            
        Returns:
            Template Attack实例
        """
        if algorithm is None:
            algorithm = self.algorithm
            
        # Create缓存键，IncludeConfigurationInformation
        cache_key = f"{algorithm}_{target_operation}_{leakage_model}"
            
        if cache_key not in self.template_attacks:
            try:
                # TryCreateAlgorithm特定的Template Attack
                template_attack = TemplateAttack.create_algorithm_template_attack(
                    algorithm, target_operation, leakage_model
                )
                self.logger.info(f"SuccessCreate {algorithm} Template Attack (操作: {target_operation}, 模型: {leakage_model})")
            except Exception as e:
                # IfFailed，Create通用Template Attack
                self.logger.warning(f"Create {algorithm} Algorithm特定Template AttackFailed: {e}")
                template_attack = TemplateAttack()
                self.logger.warning(f"Use通用Template Attack，Require手动SettingsIntermediate valueAnd泄漏模型Function")
            
            # LoadData
            if self.traces is not None:
                template_attack.traces = self.traces
                template_attack.plaintexts = self.plaintexts
                template_attack.keys = self.keys
                template_attack.ciphertexts = self.ciphertexts
            
            self.template_attacks[cache_key] = template_attack
            
        return self.template_attacks[cache_key]
    
    def set_template_attack_functions(self, algorithm: str, intermediate_value_func, leakage_model_func):
        """
        For指定AlgorithmSettingsTemplate Attack的回调Function
        
        Args:
            algorithm: Algorithm名称
            intermediate_value_func: Intermediate valueCalculateFunction func(plaintext, key, hypothesis) -> intermediate_value
            leakage_model_func: 泄漏模型Function func(intermediate_value) -> leakage_value
        """
        if algorithm not in self.template_attacks:
            # Create新的Template Attack实例
            template_attack = TemplateAttack(intermediate_value_func, leakage_model_func)
            
            # LoadData
            if self.traces is not None:
                template_attack.traces = self.traces
                template_attack.plaintexts = self.plaintexts
                template_attack.keys = self.keys
                template_attack.ciphertexts = self.ciphertexts
            
            self.template_attacks[algorithm] = template_attack
        else:
            # Update现Has实例的Function
            self.template_attacks[algorithm].set_intermediate_value_function(intermediate_value_func)
            self.template_attacks[algorithm].set_leakage_model_function(leakage_model_func)
        
        self.logger.info(f"已ForAlgorithm {algorithm} SettingsTemplate Attack回调Function")
    
    def load_data(self, npz_file: str, algorithm: Optional[str] = None) -> bool:
        """
        LoadTraceData
        
        Args:
            npz_file: NPZFilePath
            algorithm: 指定AlgorithmClass型（Optional）
            
        Returns:
            YesNoLoadSuccess
        """
        try:
            if not os.path.exists(npz_file):
                raise FileNotFoundError(f"FileNot存In: {npz_file}")
            
            self.logger.info(f"LoadTraceData: {npz_file}")
            data = np.load(npz_file, allow_pickle=True)
            
            # ExtractData
            self.traces = data.get('power_traces', data.get('traces'))
            self.plaintexts = data.get('plaintexts')
            self.ciphertexts = data.get('ciphertexts')
            self.keys = data.get('keys')
            
            if self.traces is None:
                raise ValueError("NPZFile中未找ToPowerTraceData")
            
            # 确定AlgorithmClass型
            if algorithm:
                self.algorithm = algorithm.lower()
            else:
                algorithms = data.get('algorithms')
                if algorithms is not None and len(algorithms) > 0:
                    self.algorithm = algorithms[0].lower()
                else:
                    # FromFile名推断
                    filename = os.path.basename(npz_file).lower()
                    for alg in ['aes', 'sm4', 'rsa', 'ecc', 'sm2', 'dilithium']:
                        if alg in filename:
                            self.algorithm = alg
                            break
                    else:
                        self.algorithm = 'aes'  # Default
            
            # LoadDataTo基础Attack器
            for attack_name, attack_instance in self.basic_attacks.items():
                if attack_instance is not None:  # SkipTemplate Attack
                    if not attack_instance.load_data(npz_file):
                        self.logger.warning(f"基础Attack器 {attack_name} DataLoadFailed")
            
            # InitializeAlgorithm特定Attack器
            if self.algorithm in ALGORITHM_ATTACKS:
                try:
                    attack_class = get_algorithm_attack(self.algorithm)
                    self.algorithm_attacks[self.algorithm] = attack_class()
                    
                    # LoadDataToAlgorithm特定Attack器
                    if not self.algorithm_attacks[self.algorithm].load_data(npz_file):
                        self.logger.warning(f"Algorithm特定Attack器 {self.algorithm} DataLoadFailed")
                    
                except Exception as e:
                    self.logger.error(f"InitializeAlgorithm特定Attack器Failed: {e}")
            
            # Update已存In的Template Attack实例的Data
            for template_attack in self.template_attacks.values():
                template_attack.traces = self.traces
                template_attack.plaintexts = self.plaintexts
                template_attack.keys = self.keys
                template_attack.ciphertexts = self.ciphertexts
            
            self.logger.info(f"DataLoadSuccess:")
            self.logger.info(f"  - Algorithm: {self.algorithm.upper()}")
            self.logger.info(f"  - Trace数量: {len(self.traces)}")
            self.logger.info(f"  - Trace长度: {self.traces.shape[1]}")
            self.logger.info(f"  - Plaintext数量: {len(self.plaintexts)}")
            
            return True
            
        except Exception as e:
            self.logger.error(f"DataLoadFailed: {e}")
            return False
    
    def run_basic_attack(self, attack_type: str, target_byte: int = 0, **kwargs) -> AttackResult:
        """
        Run基础Attack
        
        Args:
            attack_type: AttackClass型 (cpa, dpa, spa, template)
            target_byte: 目标字节位置
            **kwargs: 其他Parameters
                ForTemplate Attack，Support额外Parameters:
                - target_operation: 目标操作 (Default: "sbox_output")
                - leakage_model: 泄漏模型 (Default: "hamming_weight")
            
        Returns:
            AttackResult
        """
        if attack_type not in self.basic_attacks:
            raise ValueError(f"NotSupport的AttackClass型: {attack_type}")
        
        if self.traces is None:
            raise ValueError("未LoadTraceData")
        
        self.logger.info(f"Start {attack_type.upper()} Attack (目标字节: {target_byte})")
        
        # 特殊ProcessTemplate Attack
        if attack_type == 'template':
            # ExtractTemplate Attack特定Parameters
            target_operation = kwargs.pop('target_operation', 'sbox_output')
            leakage_model = kwargs.pop('leakage_model', 'hamming_weight')
            
            attack_instance = self._get_template_attack(
                algorithm=self.algorithm,
                target_operation=target_operation,
                leakage_model=leakage_model
            )
        else:
            attack_instance = self.basic_attacks[attack_type]
            
        result = attack_instance.attack(target_byte=target_byte, **kwargs)
        
        self.logger.info(f"{attack_type.upper()} AttackCompleted:")
        self.logger.info(f"  - Success: {result.success}")
        self.logger.info(f"  - 置信度: {result.confidence:.4f}")
        self.logger.info(f"  - Execute时间: {result.execution_time:.2f}秒")
        
        return result
    
    def run_algorithm_specific_attack(self, attack_type: str, target_operation: str = "sbox_output", 
                                    target_byte: int = 0, **kwargs) -> AlgorithmSpecificResult:
        """
        RunAlgorithm特定Attack
        
        Args:
            attack_type: AttackClass型 (cpa, dpa, spa, template)
            target_operation: 目标操作
            target_byte: 目标字节位置
            **kwargs: 其他Parameters
            
        Returns:
            Algorithm特定AttackResult
        """
        if self.algorithm not in self.algorithm_attacks:
            raise ValueError(f"未InitializeAlgorithm特定Attack器: {self.algorithm}")
        
        self.logger.info(f"StartAlgorithm特定 {attack_type.upper()} Attack:")
        self.logger.info(f"  - Algorithm: {self.algorithm.upper()}")
        self.logger.info(f"  - 目标操作: {target_operation}")
        self.logger.info(f"  - 目标字节: {target_byte}")
        
        attack_instance = self.algorithm_attacks[self.algorithm]
        
        # According toAttackClass型Call相应Method
        if attack_type == 'cpa':
            result = attack_instance.run_cpa_attack(
                target_operation=target_operation,
                target_byte=target_byte,
                **kwargs
            )
        elif attack_type == 'dpa':
            result = attack_instance.run_dpa_attack(
                target_operation=target_operation,
                target_byte=target_byte,
                **kwargs
            )
        elif attack_type == 'spa':
            result = attack_instance.run_spa_attack(
                target_operation=target_operation,
                **kwargs
            )
        elif attack_type == 'template':
            result = attack_instance.run_template_attack(
                target_operation=target_operation,
                **kwargs
            )
        else:
            raise ValueError(f"NotSupport的AttackClass型: {attack_type}")
        
        self.logger.info(f"Algorithm特定 {attack_type.upper()} AttackCompleted:")
        self.logger.info(f"  - Success: {result.success}")
        self.logger.info(f"  - 置信度: {result.confidence:.4f}")
        self.logger.info(f"  - Execute时间: {result.execution_time:.2f}秒")
        
        return result
    
    def run_comprehensive_attack(self, target_byte: int = 0, 
                               attack_types: List[str] = None) -> Dict[str, Any]:
        """
        Run综合Attack（多种AttackClass型）
        
        Args:
            target_byte: 目标字节位置
            attack_types: AttackClass型List
            
        Returns:
            综合AttackResult
        """
        if attack_types is None:
            attack_types = ['cpa', 'dpa', 'spa', 'template']
        
        self.logger.info(f"Start综合Attack (Algorithm: {self.algorithm.upper()})")
        
        results = {
            'algorithm': self.algorithm,
            'target_byte': target_byte,
            'basic_attacks': {},
            'algorithm_specific_attacks': {},
            'summary': {}
        }
        
        # Run基础Attack
        for attack_type in attack_types:
            try:
                result = self.run_basic_attack(attack_type, target_byte)
                results['basic_attacks'][attack_type] = asdict(result)
            except Exception as e:
                self.logger.error(f"基础 {attack_type} AttackFailed: {e}")
                results['basic_attacks'][attack_type] = {'error': str(e)}
        
        # RunAlgorithm特定Attack
        if self.algorithm in self.algorithm_attacks:
            for attack_type in attack_types:
                try:
                    result = self.run_algorithm_specific_attack(attack_type, target_byte=target_byte)
                    results['algorithm_specific_attacks'][attack_type] = asdict(result)
                except Exception as e:
                    self.logger.error(f"Algorithm特定 {attack_type} AttackFailed: {e}")
                    results['algorithm_specific_attacks'][attack_type] = {'error': str(e)}
        
        # Generate摘要
        basic_success = sum(1 for r in results['basic_attacks'].values() 
                          if isinstance(r, dict) and r.get('success', False))
        algo_success = sum(1 for r in results['algorithm_specific_attacks'].values() 
                         if isinstance(r, dict) and r.get('success', False))
        
        results['summary'] = {
            'basic_attacks_success': basic_success,
            'basic_attacks_total': len(results['basic_attacks']),
            'algorithm_specific_success': algo_success,
            'algorithm_specific_total': len(results['algorithm_specific_attacks']),
            'overall_success_rate': (basic_success + algo_success) / 
                                  (len(results['basic_attacks']) + len(results['algorithm_specific_attacks']))
        }
        
        self.logger.info(f"综合AttackCompleted:")
        self.logger.info(f"  - 基础AttackSuccess: {basic_success}/{len(results['basic_attacks'])}")
        self.logger.info(f"  - Algorithm特定AttackSuccess: {algo_success}/{len(results['algorithm_specific_attacks'])}")
        self.logger.info(f"  - 总体Success率: {results['summary']['overall_success_rate']:.1%}")
        
        return results
    
    def save_results(self, results: Union[AttackResult, AlgorithmSpecificResult, Dict], 
                    output_dir: str = "attack_results", filename: str = None) -> str:
        """
        SaveAttackResult
        
        Args:
            results: AttackResult
            output_dir: Output directory
            filename: File名（Optional）
            
        Returns:
            Save的FilePath
        """
        os.makedirs(output_dir, exist_ok=True)
        
        if filename is None:
            timestamp = time.strftime("%Y%m%d_%H%M%S")
            filename = f"attack_results_{timestamp}.json"
        
        filepath = os.path.join(output_dir, filename)
        
        # ConvertFor可序列化的Format
        if hasattr(results, '__dict__'):
            data = asdict(results) if hasattr(results, '__dataclass_fields__') else results.__dict__
        else:
            data = results
        
        with open(filepath, 'w', encoding='utf-8') as f:
            json.dump(data, f, indent=2, ensure_ascii=False, default=str)
        
        self.logger.info(f"Result已SaveTo: {filepath}")
        return filepath
    
    def get_available_algorithms(self) -> List[str]:
        """获取可用的AlgorithmList"""
        return list(ALGORITHM_ATTACKS.keys())
    
    def get_template_attack_supported_algorithms(self) -> List[str]:
        """获取Template AttackSupport的AlgorithmList"""
        supported = []
        
        # Check algorithm_specific_attacks Directory中的Algorithm
        try:
            import os
            from pathlib import Path
            
            # 获取 algorithm_specific_attacks DirectoryPath
            current_dir = Path(__file__).parent
            algo_dir = current_dir / "algorithm_specific_attacks"
            
            if algo_dir.exists():
                for item in algo_dir.iterdir():
                    if item.is_dir() and not item.name.startswith('_'):
                        # CheckYesNoHas对应的模型File
                        model_file = item / f"{item.name}_models.py"
                        if model_file.exists():
                            supported.append(item.name)
        except Exception as e:
            self.logger.warning(f"CheckAlgorithmSupport时出错: {e}")
            # 回退To已知Support的Algorithm
            supported = ['aes']
        
        # Add已Configuration自定义Function的Algorithm
        for cache_key in self.template_attacks.keys():
            algorithm = cache_key.split('_')[0]
            if algorithm not in supported:
                supported.append(algorithm)
                
        return sorted(list(set(supported)))  # 去重并Sort
    
    def get_algorithm_template_info(self, algorithm: str) -> Dict[str, Any]:
        """
        获取Algorithm的Template AttackConfigurationInformation
        
        Args:
            algorithm: Algorithm名称
            
        Returns:
            AlgorithmTemplate AttackConfigurationInformation
        """
        try:
            # 动态导入Algorithm模型
            module_path = f"algorithm_specific_attacks.{algorithm}.{algorithm}_models"
            try:
                from importlib import import_module
                models_module = import_module(module_path)
            except ImportError:
                return {"error": f"No法导入Algorithm {algorithm} 的模型Module"}
            
            # 获取模型Class
            model_class_name = f"{algorithm.upper()}LeakageModels"
            if not hasattr(models_module, model_class_name):
                return {"error": f"找NotTo模型Class: {model_class_name}"}
            
            model_class = getattr(models_module, model_class_name)
            
            return {
                'algorithm': algorithm,
                'target_operations': model_class.get_target_operations(),
                'leakage_models': list(model_class.get_leakage_models().keys()),
                'supported': True
            }
            
        except Exception as e:
            return {"error": str(e), "supported": False}
    
    def get_available_attacks(self) -> List[str]:
        """获取可用的AttackClass型List"""
        return list(self.basic_attacks.keys())
    
    def get_algorithm_info(self, algorithm: str = None) -> Dict[str, Any]:
        """
        获取AlgorithmInformation
        
        Args:
            algorithm: Algorithm名称（DefaultUseCurrentAlgorithm）
            
        Returns:
            AlgorithmInformation
        """
        if algorithm is None:
            algorithm = self.algorithm
        
        if algorithm not in ALGORITHM_ATTACKS:
            return {"error": f"NotSupport的Algorithm: {algorithm}"}
        
        try:
            attack_class = get_algorithm_attack(algorithm)
            instance = attack_class()
            
            return {
                'algorithm': algorithm,
                'parameters': instance.get_algorithm_parameters(),
                'target_operations': instance.get_target_operations(),
                'leakage_models': list(instance.create_leakage_models().keys())
            }
        except Exception as e:
            return {"error": str(e)}
    
    def plot_results(self, result: Union[AttackResult, AlgorithmSpecificResult], 
                    target_operation: str = "sbox_output", leakage_model: str = "hamming_weight"):
        """
        绘制AttackResult
        
        Args:
            result: AttackResult
            target_operation: Template Attack的目标操作（仅用于Template Attack）
            leakage_model: Template Attack的泄漏模型（仅用于Template Attack）
        """
        if isinstance(result, AttackResult):
            # 基础AttackResult
            attack_type = result.attack_type.lower()
            if attack_type == 'template':
                # Use对应Algorithm的Template Attack实例进行绘图
                template_attack = self._get_template_attack(
                    algorithm=self.algorithm,
                    target_operation=target_operation,
                    leakage_model=leakage_model
                )
                template_attack.plot_results(result)
            elif attack_type in self.basic_attacks and self.basic_attacks[attack_type] is not None:
                self.basic_attacks[attack_type].plot_results(result)
        elif isinstance(result, AlgorithmSpecificResult):
            # Algorithm特定AttackResult
            if self.algorithm in self.algorithm_attacks:
                # 这里可以AddAlgorithm特定的绘图逻辑
                self.logger.info("Algorithm特定AttackResult绘图功能待实现")
        else:
            self.logger.warning("NotSupport的ResultClass型")


def create_attack_manager(npz_file: str, algorithm: str = None, 
                         log_level: str = "INFO") -> SideChannelAttackManager:
    """
    便捷Function：Create并InitializeAttack管理器
    
    Args:
        npz_file: NPZTraceFilePath
        algorithm: AlgorithmClass型
        log_level: 日志级别
        
    Returns:
        Initialize的Attack管理器
    """
    manager = SideChannelAttackManager(log_level)
    
    if not manager.load_data(npz_file, algorithm):
        raise RuntimeError("DataLoadFailed")
    
    return manager


if __name__ == "__main__":
    # SimpleTest
    import argparse
    
    parser = argparse.ArgumentParser(description="Side-Channel Attack管理器")
    parser.add_argument('npz_file', nargs='?', help='NPZTraceFilePath')
    parser.add_argument('--algorithm', help='AlgorithmClass型')
    parser.add_argument('--attack', default='cpa', help='AttackClass型')
    parser.add_argument('--target-byte', type=int, default=0, help='目标字节')
    parser.add_argument('--comprehensive', action='store_true', help='Run综合Attack')
    parser.add_argument('--list-algorithms', action='store_true', 
                       help='列出Support的加密Algorithm及模板Information')
    
    args = parser.parse_args()
    
    # 列出Support的Algorithm
    if args.list_algorithms:
        print("=" * 70)
        print("Side-Channel Attack管理器 - Support的加密Algorithm")
        print("=" * 70)
        
        # Create临时管理器以获取AlgorithmInformation
        manager = SideChannelAttackManager()
        
        # 获取All可用Algorithm
        all_algorithms = manager.get_available_algorithms()
        # 获取Has模板Support的Algorithm
        template_algorithms = manager.get_template_attack_supported_algorithms()
        
        if not all_algorithms:
            print("\n未找ToSupport的Algorithm")
            sys.exit(0)
        
        print(f"\n基础SupportAlgorithm数量: {len(all_algorithms)}")
        print(f"AlgorithmList: {', '.join(all_algorithms)}")
        
        print(f"\nTemplate AttackSupport: {len(template_algorithms)}")
        print(f"AlgorithmList: {', '.join(template_algorithms)}")
        
        # DetailedInformation
        print("\n" + "=" * 70)
        print("AlgorithmDetailedInformation")
        print("=" * 70)
        
        for algo in all_algorithms:
            print(f"\n[{algo.upper()}]")
            print("-" * 70)
            
            # 获取AlgorithmInformation
            algo_info = manager.get_algorithm_info(algo)
            
            if 'error' in algo_info:
                print(f"  Status: 基础Support")
                print(f"  Description: {algo_info['error']}")
                print(f"  AttackMethod: CPA, DPA, SPA")
            else:
                print(f"  Status: CompleteSupport")
                
                # From parameters 中ExtractInformation
                params = algo_info.get('parameters', {})
                if params:
                    if 'type' in params:
                        print(f"  AlgorithmClass型: {params['type']}")
                    if 'key_size' in params:
                        print(f"  Key大小: {params['key_size']} bytes")
                    if 'block_size' in params:
                        print(f"  块大小: {params['block_size']} bytes")
                    if 'rounds' in params:
                        print(f"  轮数: {params['rounds']}")
                
                print(f"  AttackMethod: CPA, DPA, SPA, Template")
            
            # IfHas模板Support，Display模板Information
            if algo in template_algorithms:
                template_info = manager.get_algorithm_template_info(algo)
                if 'error' not in template_info:
                    print(f"  目标操作: {', '.join(template_info.get('target_operations', []))}")
                    print(f"  泄漏模型: {', '.join(template_info.get('leakage_models', []))}")
        
        print("\n" + "=" * 70)
        print("UseExample")
        print("=" * 70)
        print("\n# RunCPAAttack:")
        print("python3 attack_manager.py traces.npz --algorithm aes --attack cpa")
        print("\n# Run综合Attack:")
        print("python3 attack_manager.py traces.npz --algorithm aes --comprehensive")
        print("\n" + "=" * 70)
        sys.exit(0)
    
    # 原Has功能：RunAttack
    if not args.npz_file:
        parser.error("RequireProvideNPZFilePath（OrUse --list-algorithms 查看Support的Algorithm）")
    
    try:
        manager = create_attack_manager(args.npz_file, args.algorithm)
        
        if args.comprehensive:
            results = manager.run_comprehensive_attack(args.target_byte)
            print(json.dumps(results, indent=2, ensure_ascii=False, default=str))
        else:
            result = manager.run_basic_attack(args.attack, args.target_byte)
            print(f"AttackResult: Success={result.success}, 置信度={result.confidence:.4f}")
            
    except Exception as e:
        print(f"Error: {e}")
        sys.exit(1)
